#!/usr/bin/wish -f
#
# Copyright (c) 2020 NVI, Inc.
# but see subset below:
# Copyright (c) 1992-1993 The Regents of the University of California.
#
# This file is part of VLBI Field System
# (see http://github.com/nvi-inc/fs).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# fsvue source for the tcl/Tk toolkit
# Basic font for button, menus and labels
# Product of NVI,Inc./GSFC (2000)
# to be incorporated into the VLBI Field System.
# Window manager configurations

# Set up fsvue directories.
  set ICONDIR /usr2/fs/fsvue/images
  set FSDIR /usr2/fs
  set BINDIR /usr2/fs/bin
  set LIBDIR /usr2/fs/fsvue/lib
  set LIBDEF /usr2/fs/fsvue/def_lib
  set LOGDIR /usr2/log

# Get the monitors screen information.
  set vieX [winfo screenwidth .]
  set vieY [winfo screenheight .]  

# Set up window (canvas).
  global tkVersion
  wm positionfrom . user
  wm sizefrom . ""
  wm maxsize . 1152 900
  wm iconposition . 1200 500
  wm iconbitmap . @$ICONDIR/vlb.icon
  wm iconname . {fsvue}
#position window full screen from top left corner.
#  wm geometry . $vieX\x$vieY+0+0
#position window from top left corner.
#  wm geometry . +0+0
  wm title . {FS VLBI User Environment [ SERVER ]}
  wm frame .
  set w .
#  wm deiconify .
  $w config -cursor {top_left_arrow black white}

# Globals used throughout.
  global inpipe stopscroll line w semchk cmd cid

# Decide on font size.
  if {$argv=="D"} {
      exec $LIBDEF/fsvue &; exit
  } elseif {$argv=="F"} {
      set bfont [exec $LIBDIR/vue_sysfonts {}]
      set fontsize $bfont
      set ibfont [open $LIBDIR/my_font w+]
      puts $ibfont $bfont
      catch {close $ibfont}
  } else { 
      set ibfont [open "|/bin/sh -c \"cat $LIBDIR/my_font; :\""]
      set bfont [gets $ibfont]
#      set newfile_filename [lindex $argv 1]
      set fontsize $bfont
      catch {close $ibfont}
  }

# Find out if the Field System is running by
# checking fsvue_running flag in SHM.
#  if {[ exec vueinfo fsvueg ]} {
#      exec $LIBDIR/fsvueC &; exit
#  }
# Set the fsvue_running if I got pass the test above.
#  exec vueinfo fsvuey

# Use an associative array to store keys and commands.
  set cmd(Calculator) "$LIBDIR/vue_fscalq $fontsize"
#  set cmd(OLD_FS) "xterm -C -ls -sb -name login_sh -fn 10x20 -geometry 99x24+0+0 -e fs"
  set cmd(FS_Console) "xterm -geom 60x5+0+650 -e $BINDIR/oprin"
  set cmd(Send_mail) "$LIBDIR/vue_fsmail $fontsize"
  set cmd(Netscape_mail) "netscape -mail"
  set cmd(FS_Ready_Form) "$FSDIR/msg/msg"
  set cmd(lognm) "xterm -bg black -fg white -sb -sl 1000 -e $BINDIR/lognm"
  set cmd(pfmed) "xterm -bg black -fg white -sb -sl 1000 -e $BINDIR/pfmed"
  set cmd(setcl) "xterm -bg black -fg white -sb -sl 1000 -e $BINDIR/setcl"
  set cmd(logpl) "$BINDIR/logpl"      
  set cmd(pdplt) "xterm -bg black -fg white -sb -sl 1000 -e $BINDIR/pdplt"
  set cmd(xterm) "xterm -bg black -fg white -cr yellow -geometry +10+120 -fn 10x20"

# File storage
  set xfsfile "~/.xfscmds"
  set global_startmode 0            ;# 0=Interactive mode; 1=Command-line mode
#set current_filename [lindex $argv 0]
  set current_filename ""           ;# The selected log file
  set current_DefaultDir /usr2/log  ;# Default directory for FS log files
  set stopscroll 0
# Set the log file to station.log to start out with.
  set newfile_filename "station.log" 

# Results
  set val01 [exec vueinfo time]
  set val02 $newfile_filename
  set val03 [exec vueinfo rack]
  set val04 [exec vueinfo drive1]
  set val05 [exec vueinfo drive2]
  set val06 [exec vueinfo site]
  set val07 [exec vueinfo lskd]
  set val08 [exec vueinfo ifs]
  set val09 $val02

# Top frame is a menubar
# there is more magic that you can do with this
# build widget .m and .top
frame .m \
	-bg {navy} \
	-borderwidth {2} \
	-relief {groove} 

frame .top \
    -bg {blue} \
    -relief {groove} 

#pack .top -side bottom -fill both
# ==========================================================================
#
#       SECTION TO COOK UP THE BUTTONS AND PACK THEM.
#
# ==========================================================================
# two buttons in the menu giving dropdown menus
menubutton .m.file -text "File" -relief {raise} -font $bfont -menu .m.file.menu -background navy -activebackground red -fg white

menubutton .m.dsp -text "Displays" -relief {raise} -font $bfont -menu .m.dsp.menu -background navy -activebackground red -fg white

menubutton .m.cmd -text "Execute" -relief {raise} -font $bfont -menu .m.cmd.menu -background navy -activebackground red -fg white

button .m.fshelp -text "Field System HELP" -relief {raise} -font $bfont -background navy -activebackground red -fg white -command {exec $LIBDIR/vue_fshelp $fontsize &}

button .m.fs -text "Examine LOGS" -relief {raise} -font $bfont -background navy -activebackground red -fg white -command {exec $LIBDIR/vue_fslog $fontsize $LOGDIR/$newfile_filename &}

button .m.fso -text "Other Files" -relief {raise} -font $bfont -background navy -activebackground red -fg white -command {exec $LIBDIR/vue_fsfiles $fontsize &}

button .m.q -text "Exit" -relief {raise} -font $bfont -background red -activebackground red -fg white -command { if { [exec vueinfo chksem] == "fs already running" } {
    set choice [tk_messageBox -type yesnocancel -default no \
                    -message "Are you sure you want to terminate the Field System this way?\n\nIt would be better to terminate it in the oprin command window, then exit fsvue." \
                    -icon question];
    if {[regexp "yes" $choice] == 1} { Stop_FS }
} else {
    set choice [tk_messageBox -type yesnocancel -default no \
                    -message "Are you sure you want to kill the fsvue window?"\
                    -icon question];
    if {[regexp "yes" $choice] == 1} { Stop_FS }
}
}

menubutton .m.help -bitmap @$ICONDIR/info.icon -menu .m.help.menu -relief {raise} -font $bfont -menu .m.help.menu -background navy -activebackground red -fg white

entry .m.ent -relief {sunken} -bg linen -fg black

pack .m.help .m.file .m.dsp .m.cmd .m.fs .m.fso -side left -fill both -expand 1
#pack .m.help .m.file .m.dsp1 .m.dsp .m.cmd .m.fs .m.fso -side left -fill both -expand 1

# Main command entry area is under that
pack .m.fshelp .m.q  -side left -fill both -expand 0
#pack .m.fshelp -side left -fill both -expand 0
pack .m -side top -fill x -expand 0

# Put the focus into the box
bind .m.ent <Return> {Execute}
focus .m.ent

# build widget .m2 for FS info.
frame .m2 \
    -bg {blue} \
    -borderwidth {0} \
    -relief {groove} 

#pack .m2 -side bottom -fill x -expand 1
pack .m2 -side bottom -fill x -expand 0

# ==========================================================================
#
#                    SECTION FOR DISPLAY 
#
# ==========================================================================
proc displayWin { } {
    global val01 val02 val03 val04 val05 val06 val07 val08 val09
    global txt01 txt02 txt03 txt04 txt05 txt06 txt07 txt08 txt09
    global bfont

    frame .m1 \
	    -bg {blue} \
	    -borderwidth {5} \
	    -relief {groove} 

    label .m1.txt02 -font $bfont -background blue -fg white -text "SCHEDULE"
    label .m1.txt03 -font $bfont -background blue -fg white -text "RACK"
    label .m1.txt04 -font $bfont -background blue -fg white -text "DRIVES"
    label .m1.txt05 -font $bfont -background blue -fg white -text "SITE"
    label .m1.txt08 -font $bfont -background blue -fg white -text "IF Attenuators"
    label .m1.txt09 -font $bfont -background blue -fg white -text "LOG FILE"
    label .m1.val02 -font $bfont -textvariable val02 -background white -fg black
    label .m1.val03 -font $bfont -textvariable val03 -background white -fg black
    label .m1.val04 -font $bfont -textvariable val04 -background white -fg black
    label .m1.val05 -font $bfont -textvariable val05 -background white -fg black
    label .m1.val06 -font $bfont -textvariable val06 -background white -fg black
    label .m1.val07 -font $bfont -textvariable val07 -background white -fg black
    label .m1.val08 -font $bfont -textvariable val08 -background white -fg black
    label .m1.val09 -font $bfont -textvariable val09 -background white -fg black
    pack .m1 -side left  -fill both
    pack .m1.txt05
    pack .m1.val06 -fill both
    pack .m1.txt02
    pack .m1.val07 -fill both
    pack .m1.txt03
    pack .m1.val03 -fill both
    pack .m1.txt04
    pack .m1.val04 -fill both
    pack .m1.val05 -fill both
    pack .m1.txt08
    pack .m1.val08 -fill both
    pack .m1.txt09
    pack .m1.val09 -fill both
}
# Setup display window to the left
displayWin

# Just a Timer
proc displayTimer {} {
    global val01 bfont
    label .m1.txt01 -font $bfont -background blue -fg white -text "UT:"
    label .m1.val01 -font $bfont -textvariable val01 -background white -fg black
    pack .m1.txt01
    pack .m1.val01 -fill both

}

# Setup FS clock?
# ==========================================================================
#
#           SECTION FOR COOKING UP THE ITEMS UNDER THE BUTTONS.
#
# ==========================================================================
# File menu
menu .m.file.menu  -background blue -fg white
.m.file.menu add command -label Load -font $bfont -command LoadFile
.m.file.menu add command -label Save -font $bfont -command SaveFile

menu .m.dsp.menu -background blue -fg white
.m.dsp.menu add command -label "Monit: time C-S-1" -font $bfont -command {DSPit monit1}
.m.dsp.menu add command -label "Monit: status C-S-2" -font $bfont -command {DSPit monit2}
.m.dsp.menu add command -label "Monit: Tsys C-S-3" -font $bfont -command {DSPit monit3}
.m.dsp.menu add command -label "Monit: DAS C-S-4" -font $bfont -command {DSPit monit4}
.m.dsp.menu add command -label "Monit: Mark5 C-S-5" -font $bfont -command {DSPit monit5}
.m.dsp.menu add command -label "Cheker C-S-C" -font $bfont -command {DSPit chekr}
.m.dsp.menu add command -label "Emacs C-S-E" -font $bfont -command { exec emacs &;}
.m.dsp.menu add command -label "Logex C-S-L" -font $bfont -command {DSPit logex}
.m.dsp.menu add command -label "Pfmed C-S-P" -font $bfont -command {DSPit pfmed}
.m.dsp.menu add command -label "Setcl C-S-S" -font $bfont -command {DSPit setcl}
.m.dsp.menu add command -label "Fmset C-S-T" -font $bfont -command {DSPit fmset}
.m.dsp.menu add command -label "New Window C-S-W" -font $bfont -command {DSPit new_xwin}

.m.dsp.menu add command -label Weather -font $bfont -command {exec $LIBDIR/vue_fswx $fontsize &}

# Help menu
menu .m.help.menu -background blue -fg white
.m.help.menu add command -label "Logo" -font $bfont -command {exec $LIBDIR/vue_logo &}
.m.help.menu add command -label "About fsvue" -font $bfont -command {Help VUE}
.m.help.menu add command -label "Using fsvue" -font $bfont -command {Help using}
.m.help.menu add command -label "Menus" -font $bfont -command {Help menus}
.m.help.menu add command -label "Aliases & Commands" -font $bfont -command {Help commands}
 
# Command menu
menu .m.cmd.menu -background blue -fg white
.m.cmd.menu add command -label Add -font $bfont -command AddCmd
.m.cmd.menu add separator

# ==========================================================================
#
#            SECTION FOR COOKING UP PROCEDURES
#
# ==========================================================================
proc forAllMatches { w pattern script} {
    scan [$w index end] %d numLines
    for {set i 1} {$i < $numLines} {incr i} {
	$w mark set last $i.0
	while { [regexp -indices $pattern \
		[$w get last "last lineend"] indices]} {
	    $w mark set first \
			"last + [lindex $indices 0] chars"
		$w mark set last "last + 1 chars \
			+ [lindex $indices 1] chars"
		uplevel $script
	    }
#    }
}
# -----------------------------------------
# setup a display monitor on a growing file
# NOT USED but Kept around.
# -----------------------------------------
#
proc AnotherLog {} {
    global inpipe newfile_filename pids
    incr pids 1
    catch {exec kill $pids}
 #    exec kill $pids
    execAndLog "tail -f -n 24 /usr2/log/$newfile_filename"
}

# help from WWW for FS installation and other things.
#.m2.t3 tag bind big <Button-2> {
#        open_html lupus.gsfc.nasa.gov/fs
#}


# ==========================================================================
#
#          CONTINUE COOKING PROCEDURES SECTION
#
# ==========================================================================
#
proc open_html {file} {
    global tcl_platform

    switch $tcl_platform(platform) {
	unix { 
	    set cmd "exec netscape -remote \"openFile($file)\""
	    if {[catch $cmd] !=0} {
		exec netscape &
		while {[catch $cmd] !=0} {
		    after 500
		}
	    }
	}
	window {
	    set cmd [list exec netscape $file &]
	    if {[catch $cmd] !=0} {
		set prog [tk_getOpenFile -title "Where is Netscape?"]
		if {$prog != " "} {
		    exec $prog $file &
		}
	    }
	}
    }
}

# ---------------------
# Field System Displays
# ---------------------
proc DSPit dspname {
    global BINDIR
    if {$dspname == "monit1"} {
	exec xterm  -title "Field System Time" -geom 40x1+0+0 \
	    -e /usr2/fs/bin/$dspname &
    }
    if {$dspname=="monit2"} {
	exec xterm -title "System Status Monitor" -geom 81x6+0+0 \
	    -e /usr2/fs/bin/$dspname &
    }
    if {$dspname=="monit3"} {
	exec xterm -title "System Temperature" -geom 32x17+0+120 \
	    -e /usr2/fs/bin/$dspname &
    }
    if {$dspname=="monit4"} {
	exec xterm -ls -title "LBA DAS Monitor" -geom 80x24+0+160 \
	    -e /usr2/fs/bin/$dspname &
    }
    if {$dspname=="monit5"} {
	exec xterm -title "Mark 5 Remaining Capacity" -geom 46x3+0+157 \
	    -e /usr2/fs/bin/$dspname &
    }
    if {$dspname=="chekr"} {
	exec run -w $BINDIR/$dspname &
    }
    if {$dspname=="emacs"} {
	exec emacs &
    }
    if {$dspname=="logex"} {
	exec xterm -title logex -e $BINDIR/$dspname &
    }
    if {$dspname=="pfmed"} {
	exec xterm -title pfmed -e $BINDIR/$dspname &
    }
    if {$dspname=="setcl"} {
	exec run -w $BINDIR/$dspname &
    }
    if {$dspname=="fmset"} {
	exec xterm -title fmset -e $BINDIR/$dspname &
    }
    if {$dspname=="new_xwin"} {
	exec xterm -geom 80x24+75+75 -rw &
    }
    if {$dspname=="errchk"} {
	exec xterm -geom 90x10+90+0 -bg linen -fg black \
		-sb -sl 1000 -e /usr2/fs/bin/$dspname &
    }
}

# ---------------------------------------------------------------
# Routine to load the Command Menu dynamically from the cmd array
# each menu entry will call the procedure ExFromMenu with an
# argument of the command name
# ---------------------------------------------------------------
proc LoadCmdMenu {} {
        global cmd bfont

        foreach name [lsort [array names cmd]] {
                set c "ExFromMenu $name"
	    .m.cmd.menu add command -label $name -font $bfont -command $c
        }
}

# -------------------------------------
# Load the command menu at startup time
# -------------------------------------
#
LoadCmdMenu

# -------------------------------------------------------
# That's all the top level windows
# Now we have a bunch of actions to do things
#
# The execute routine. Called when Return is typed in the
# main entry window and also from the Command Menu
# -------------------------------------------------------
proc Execute {} {
        global cmd
        
        set str [.m.ent get]
        .m.ent delete 0 end
        set other_cmd $str
        set str "[MinMatch $str]"
        if { $str == "" } {
	    puts $other_cmd
	    eval exec $other_cmd &
                return
        }
        set val $cmd($str)
        if { $val == "" } {
                return
        }

        switch $val {
        quit    {       exit    }
        default {
                       .m.ent delete 0 end
                        eval exec $val &
                }
        }
}

# ----------------------------
# Minimum length matching code
# ----------------------------
proc MinMatch { str } {
        global cmd
        
        set found ""
        foreach name [lsort [array names cmd]] {
                if { [string match $str* $name] } {
                        if { $found != "" } {
                                return ""
                        } else {
                                set found $name
                        }
                }
        }
        return $found
}

# -------------------------------------------------
# Called from the Command menu to execute a command
# -------------------------------------------------
proc ExFromMenu {name} {

        .m.ent delete 0 end
        .m.ent insert end $name
        Execute
}

# ----------------------------------------------------------
# Load the cmd array from a file
# currently this is called .xfscmds in the current directory
# You should change this
# ----------------------------------------------------------
proc LoadFile {} {
        global cmd xfsfile

        if { [file exists $xfsfile] } {
                set f [open $xfsfile r]
                while { [gets $f line] >= 0 } {
                        set line [split $line ":"]
                        set new [lindex $line 0]
                        set cmd($new) [join [lrange $line 1 end] ":"]
                }
                close $f
        }
        .m.cmd.menu delete 2 last
        LoadCmdMenu

}

# ----------------------------------
#       Executed as we start working
# ----------------------------------
LoadFile

# --------------------------
# The converse - save a file
# --------------------------
proc SaveFile {} {
        global cmd xfsfile

        set f [open $xfsfile w]
        foreach name [lsort [array names cmd]] {
                puts $f "$name:$cmd($name)"
        }
        close $f
}

# ---------------------------------------------
# Called from the Add entry in the command menu
# creates a pop-up window
# ---------------------------------------------
proc AddCmd {} {
        global cmd bfont

        # on error kill this
        catch {destroy .pop}
        # make a toplevel item
        toplevel .pop -bg linen

        # add a title for the Window Manager to use
        wm title .pop "Add Command"
        
        # the outer frame
        frame .pop.f -bd 2
        pack .pop.f -side top -fill both

        # The frame is a title, and entry box, another title and another
        # entry box
        label .pop.f.lab1 -text "Command Name" -font $bfont
        entry .pop.f.e1 -relief sunken
        label .pop.f.lab2 -text "Command" -font $bfont
        entry .pop.f.e2 -relief sunken
        pack .pop.f.lab1 .pop.f.e1 .pop.f.lab2 .pop.f.e2 -side top
        # The bottom of the frame has two buttons, one to get rid of this
        # diaglogue box, one to load the cmd vector
        frame .pop.f.m -bd 2 -bg linen
        pack .pop.f.m -fill x -expand yes -side top

        button .pop.f.m.d -text "Dismiss" -font $bfont -command PopDown
        button .pop.f.m.l -text "Load" -font $bfont -command LoadIt
        pack .pop.f.m.d .pop.f.m.l -side left -expand yes -fill x

        # we set the focus to the top box, when we type return in that
        # the cursor goes to the second nox
        bind .pop.f.e1 <Return> {focus .pop.f.e2}
        # a return here means load the command array
        bind .pop.f.e2 <Return> {LoadIt}

        # now get the geometry right.
        # this is somewhat magic, but the idea is to remove it from
        # the screen, work out where to place it and then make it
        # visible again
        wm withdraw .pop
        update idletasks
        set xy [split [wm geom .] "+x"]
        set x [lindex $xy 2]
        set y [lindex $xy 3]
        set x [expr $x + 10 ]
        set y [expr $y + 10 ]
        wm geom .pop "+$x+$y"
        wm deiconify .pop

        # save the old focus
        set oldFocus [focus]
        # stop the main window taking events, nothing can happen there until
        # we leave from this window
        grab .pop
        # set the focus
        focus .pop.f.e1
        # wait until this top level window dies
        tkwait window .pop
        # when that happens reset the focus     
        focus $oldFocus
        # load the Command menu and resume
        LoadCmdMenu
	# reload so as not the see two listings 
	LoadFile
}

# ---------------------------------------------------
# Called from the Dismiss button, just kill the popup
# ---------------------------------------------------
proc PopDown {} {
        destroy .pop
}

# ------------------------------------------------------------
# Load the cmd vector from the contents of the two entry boxes
# and kill the popup
# ------------------------------------------------------------
proc LoadIt {} {
        global cmd

        set c [.pop.f.e1 get]
        set v [.pop.f.e2 get]
        if { $c != "" && $v != "" } {
                set cmd($c) $v
        }
        PopDown
}

# ----------------------
#       Help procedure
# ----------------------
proc Help {sel} {
        global cmd
# long lines to allow msg to format things

       set h(VUE) {Field System VLBI User Environment (fsvue)

Pronounced: 'f' 's' 'view' or just 'view'.

 fsvue is a Tcl/Tk program that monitors the Field System. It places emphasis on errors generated by the FS by making them the color 'RED'. fsvue also has other features.

The following are features included in fsvue:

[i]
Gives you information on fsvue.

[File]
This will allows you to [Load] the stored commands from a file called .xfscmds in your home directory, it also has an option [Save] commands added by the [Add] command under the button [Execute].

[Displays]
This has a menu of popup displays used by the Field System. General, Time, Tsys, DAS, and Weather together with other commands that might be added later.
           
[Execute]
This will display a menu with all the known command names and also allows you to add commands using the [Add] entry. 

[Examine LOGS]
This will popup a window that will help you examine passed logs. Information on how to use it is under the [i] button in the popup window.

[Other Files]
This will popup a window that will help you examine Field System related files. Information on how to use it is under the [i] button in the popup window.

[Field System HELP]
This will popup a window that will contain the help files from the Field System.

[Exit] - Get out of fsvue.

[ Main Window ]
This window will display FS related information.

[<< (Left botton mouse click HERE) to start the Field System >>] 
Press this bar to start the Field System.

[User input below -- Field System is up and running]
The bar above will change to active once the Field System has started with the above label. 

Command:[                ]
Commmand window. Same as oprin on the FS. Commands will echo in the window below.

 }

       set h(using) { Pretty obvious how to use fsvue. Think of it as a menu driven system with the exception of the command window.

The Command: window requires command line entries. Just like any other command line driven system. Just think of it as the OLD oprin command line xterm.
}

        set h(menus) {The File menu allows you to load the stored commands from a file called .xfscmds on your home directory.
The Execute menu displays all the known command names and also allows you to add commands using the Add entry. This pops up a window where you type a new keyword and command.
The Help Menu prints Help.}

        if { $sel == "commands" } {
                set h(commands) {Key    Alias
	}
                foreach name [lsort [array names cmd]] {
                        set h(commands) \
                                [format "%s\n%-7s\t%s" $h(commands) $name $cmd($name)]
                }
        }
        tk_dialog .help "Information" $h($sel) {} -1 OK
}

# -----------------------------------------------------------------------------
# This is a standard bit of code, modified to use my font
# dialog.tcl --
#
# This file defines the procedure tk_dialog, which creates a dialog
# box containing a bitmap, a message, and one or more buttons.
#
# $Header: /user6/ouster/wish/library/RCS/dialog.tcl,v 1.4 93/08/16 16:59:52 ouster Exp $ SPRITE (Berkeley)
#
# Copyright (c) 1992-1993 The Regents of the University of California.
# All.vpeople.rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and its documentation for any purpose, provided that the
# above cop.vpeople.right notice and the following two paragraphs appear in
# all copies of this software.
#
# IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
# OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
# CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
#
# tk_dialog:
#
# This procedure displays a dialog box, waits for a button in the dialog
# to be invoked, then returns the index of the selected button.
#
# Arguments:
# w -           Window to use for dialog top-level.
# title -       Title to display in dialog's decorative frame.
# text -        Message to display in dialog.
# bitmap -      Bitmap to display in dialog (empty string means none).
# default -     Index of button that is to display the default ring
#               (-1 means none).
# args -        One or more strings to display in buttons across the
#               bottom of the dialog box.
# ---------------------------------------------------------------------------
#
proc tk_dialog {w title text bitmap default args} {
    global tk_priv bfont

    # 1. Create the top-level window and divide it into top
    # and bottom parts.
    set ICONDIR /usr2/fs/fsvue/images

    catch {destroy $w}
    toplevel $w -class Dialog
    wm title $w $title
    wm iconbitmap $w @$ICONDIR/vlb.icon
    wm iconname $w {fsvue}
    frame $w.top -relief raised -bd 1 -bg navy
    pack $w.top -side top -fill both
    frame $w.bot -relief raised -bd 1 -bg navy
    pack $w.bot -side bottom -fill both

    # 2. Fill the top part with bitmap and message.

    message $w.msg -width 8i -text $text -font $bfont
    pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 5m -pady 5m
    if {$bitmap != ""} {
        label $w.bitmap -bitmap $bitmap
        pack $w.bitmap -in $w.top -side left -padx 5m -pady 5m
    }

    # 3. Create a row of buttons at the bottom of the dialog.

    set i 0
    foreach but $args {
        button $w.button$i -text $but -command "set tk_priv(button) $i"
        if {$i == $default} {
            frame $w.default -relief sunken -bd 1 -bg linen
            raise $w.button$i $w.default
            pack $w.default -in $w.bot -side left -expand 1 -padx 3m -pady 2m
            pack $w.button$i -in $w.default -padx 2m -pady 2m \
                    -ipadx 2m -ipady 1m
            bind $w <Return> "$w.button$i flash; set tk_priv(button) $i"
        } else {
            pack $w.button$i -in $w.bot -side left -expand 1 \
                    -padx 3m -pady 3m -ipadx 2m -ipady 1m
        }
        incr i
    }

    # 4. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display and de-iconify it.

    wm withdraw $w
    update idletasks
    set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
            - [winfo vrootx [winfo parent $w]]]
    set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
            - [winfo vrooty [winfo parent $w]]]
    wm geom $w +$x+$y
    wm deiconify $w

    # 5. Set a grab and claim the focus too.

#    set oldFocus [focus]
#    grab $w
#    focus $w

    # 6. Wait for the user to respond, then restore the focus and
    # return the index of the selected button.

    tkwait variable tk_priv(button)
    destroy $w
#    focus $oldFocus
    return $tk_priv(button)
}

# ==========================================================================
#
#                     SECTION FOR FILESELECTION 
#
# ==========================================================================
#
proc fileselection_dialog {} {
 
 global global_startmode current_DefaultDir newfile_filename current_filename

 set con 1
 set types {
  {{Log Files} {*.log} }
  {{All Files} {*} }
 }

 set current_filename [tk_getOpenFile -title "Open new log file" -filetypes $types -initialdir $current_DefaultDir]
# set newfile_filename $current_filename
# set newfile_filename [tk_getOpenFile -title "Open new log file" -filetypes $types -initialdir $current_DefaultDir]

 if {$newfile_filename != ""} {
     .t delete 1.0 end
      set $newfile_filename [lrange $current_filename 10 end]
     .t2 delete 1.0 end
     .t2 insert end "You are now viewing $newfile_filename"
      AnotherLog 
 }
}
proc after_debug {} {
    toplevel .afterdb
    wm title .afterdb "After: Debug Info"
    text .afterdb.t -width 50 -height 10 -wrap none
    pack .afterdb.t -fill both -expand yes
    after_debug_update
}
proc after_debug_update {} {
    if {[winfo exists .afterdb.t]} {
	.afterdb.t delete 1.0 end
	foreach t [after info] {
	    .afterdb.t insert end "$t\t[after info $t]\n"
	}
	after 100 after_debug_update
    }
}

#===================================================#
#  CCCCCC  LL      IIII  EEEEEE  NN    NN  TTTTTTT  #
# CC       LL       II   EE      NNNN  NN     TT    #
# CC       LL       II   EEEEE   NN NN NN     TT    #
# CC       LL       II   EE      NN  NNNN     TT    #
#  CCCCCC  LLLLLL  IIII  EEEEEE  NN    NN     TT    #
# Client                                            #
# ==================================================#
# Client gets the information from fsvue(Server)    #
#===================================================#
set WINFONT -b&h-lucidatypewriter-bold-r-normal-sans-14-140-75-75-m-90-iso8859-1
frame .op \
    -bg {black} \
    -relief {groove} 

text .tC -height 20 -width 90 -background blue -yscrollc {.sbC set} -font $WINFONT -bg linen
scrollbar .sbC -bg linen -command {.tC yview}

#bind .tC <Button-1> { pack .m.dsp.menu }

########## Client client_handle #######
# Setup the client to receive messages.
proc client_handle {} {
    global buffer cid request cmd
    global val02 val03 val04 val05 val06 val07 
    global val08 val08 val09  newfile_filename
    set i 0
#    wm title . {FS VLBI User Environment Monitor (Client)}
#    pack .op -side top -fill both -expand 0
    pack .op -side top -fill both
    pack .sbC -side right -fill y
    pack .tC  -fill both -expand 1

    set val02 $newfile_filename
    set val03 [exec vueinfo rack]
    set val04 [exec vueinfo drive1]
    set val05 [exec vueinfo drive2]
    set val06 [exec vueinfo site]
    set val07 [exec vueinfo lskd]
    set val08 [exec vueinfo ifs]
    set val09 [exec vueinfo log]
    set newfile_filename $val09

    if { [catch client_send 0 ] } { }
    if { [gets $cid request] <= 0 } {
	catch {close $cid}
	.tC insert end "Lost connection to server\n"
	Stop_Client 
    } else {
       if {[string match $buffer $request]} {
            update idletasks
       } else {
	   set buffer $request
	   update idletasks
	   if {[regexp "ERROR" $request] == 1} {
	       if {[regexp " ma " $request] == 1 || 
		   [regexp " ch " $request] == 1 ||
		   [regexp " bo " $request] == 1} {
		   .tC tag configure "red_rev" -background Red -foreground linen
		   .tC insert end [lindex $request 0]\n red_rev
	       } elseif {[regexp " mc " $request] == 1 ||
			 [regexp " ib " $request] == 1 ||
			 [regexp " an " $request] == 1 ||
			 [regexp " ds " $request] == 1} {
		   .tC tag configure "red_und" -background Red -foreground white
		   .tC insert end [lindex $request 0]\n red_und
	       } elseif {[regexp " ta " $request] == 1 ||
			 [regexp " wx " $request] == 1 ||
			 [regexp " sc " $request] == 1 } {
		   .tC tag configure "red" -background linen -foreground Red
		   
		   .tC insert end [lindex $request 0]\n red
	       } elseif {[regexp " if " $request] == 1 || 
			 [regexp " sp " $request] == 1 } {
		   .tC tag configure "blue" -background linen -foreground Blue
		   .tC insert end [lindex $request 0]\n blue
	       } else {
		   .tC insert end [lindex $request 0]\n ta
	       }
	       .tC see end
	   } elseif {[regexp "terminate" $request] == 1 } {
	       .tC insert end [lindex $request 0]\n
	       catch {exec killall oprin }
	       update idletasks
	       if { [catch client_send 0 ] } { }
	   } else {
	       if {[regexp ">  " $request] == 1 } {
		   .tC tag configure "red" -background linen -foreground Red
		   .tC insert end [lindex $request 0]\n red
	       } else {
		   .tC insert end [lindex $request 0]\n
	       }
	       .tC see end
	   }
	   update idletasks
       }
    }
}
########## Client client_send #######
# Request a message from server
proc client_send {args} {
    global cid

    if {$cid != ""} {
	puts $cid $args
    }
}

########## Client Stop #######
# Stop a client.
proc Stop_Client {} {
    global cid

    catch {close $cid}
}

########## Client Start #######
# Start a client.
proc Start {} {
    global  request buffer cid bfont

    if { [catch "socket localhost 8433"] } {
	wm title . {FS VLBI User Environment Monitor [NO SERVER AVAILABLE] }
	catch { destroy .m.q }
	button .m.q -text "Exit" -relief {raise} -font $bfont -background red -activebackground red -fg white -command { if { [exec vueinfo chksem] == "fs already running" } {
	    set choice [tk_messageBox -type yesnocancel -default no \
			    -message "Are you sure you want to kill the fsvue Client window?"\
			    -icon question];
	    if {[regexp "yes" $choice] == 1} { exit; }
	} else {  exit; }
	}
        pack .m.q  -side top -fill both -expand 1
	catch { destroy .m1 }
#	menubutton .m.shm -text "SHMEM" -relief {raise} -font $bfont -menu .m.shm.menu -background navy -activebackground red -fg white
#	pack .m.shm -side top -fill both
#	pack .sbC -side right -fill y
#	pack .tC  -fill both -expand 1
#	menu .m.shm.menu -background blue -fg white
#	.m.shm.menu add command -label General -font $bfont -command {
#	    .tC see end
#	    .tC insert end [exec vueinfo fscom]\n}
#	    .tC see end
    } else {
	wm title . {FS VLBI User Environment Monitor [ CLIENT ]}
	catch { destroy .m.q }
	button .m.q -text "Exit" -relief {raise} -font $bfont -background red -activebackground red -fg white -command { if { [exec vueinfo chksem] == "fs already running" } {
	    set choice [tk_messageBox -type yesnocancel -default no \
			    -message "Are you sure you want to kill the fsvue Client window?"\
			    -icon question];
	    if {[regexp "yes" $choice] == 1} { exit; }
	} else {  exit; }
	}
	    pack .m.q  -fill both -expand 1
	set cid [socket localhost 8433]
	fconfigure $cid -blocking 0 -buffering line
	fileevent $cid readable "client_handle"
	set buffer ""
	client_send 0
    }
}

# ####################################################
# This might be a better way of handleing the clients.
# in the future.
#
#       set parser [interp create -safe]
#       $parser eval { return }
#==================================================#
# END of Client Code                               #
#==================================================#
#
#==================================================#
# START of fsvue main Code                         #
#==================================================#
#           mm   mm    aa    iii  nn   n           #
#           m m m m   a  a    i   n n  n           #
#           m  m  m   aaaaa   i   n  n n           #
#           m     m  a     a iii  n   nn           #
# main               MAIN                          #
# =================================================#
# This is where the real work takes place.         #
# Run FS and log the IO from STDOUT.               #
#==================================================#
########## Server server_accept ######################
# Open a socket for others to read.   
proc server_accept {sid addr port} {
    fconfigure $sid -blocking 0 -buffering line
    fileevent $sid readable "server_handle $sid"
}
########## Server server_handle ######################
# Server message handler and sender for clients.
proc server_handle {sid} {
    global line w request
    
    if {[gets $sid request] < 0} {
	close $sid
    } else {
	update idletasks
	puts $sid [list $line]
    }
    update idletasks
}

# Create a frame for buttons and entry.
pack .top -side top -fill both

# Create the command button.
set but [button .top.run -text \
 " "  -relief raised -background blue -foreground white -activebackground red -command FS]

# Create a labeled entry for the command
entry .top.cmd -width 10 -relief sunken -textvariable command

# Set up keybinding equivalents to the buttons
bind .top.cmd <Return> FS

# setup display area( text and scrollbar) for monitoring.
text .t -height 20 -yscrollc {.sb set} -font $bfont -bg linen
scrollbar .sb -bg linen -command {.t yview}
text .t2 -height 1 -font $bfont -bg white -fg Red

# get the logfile being used from SHMEM.
set newfile_filename [exec vueinfo log]

bind . <Control-Shift-exclam> \
    { exec xterm -title "Field System Time" -geom 40x1+0+0 \
          -e $BINDIR/monit1 &}
bind . <Control-Shift-at> \
    { exec xterm -title "System Status Monitor" -geom 81x6+0+0 \
	  -e $BINDIR/monit2 &}
bind . <Control-Shift-numbersign> \
    { exec xterm -title "System Temperature" -geom 32x17+0+120 \
          -e $BINDIR/monit3 &}
bind . <Control-Shift-dollar> \
    {exec xterm -title "LBA DAS Monitor" -geom 80x24+0+160 \
         -e $BINDIR/monit4 &}
bind . <Control-Shift-percent> \
    {exec xterm -title "Mark 5 Remaining Capacity" -geom 46x3+0+157 \
         -e $BINDIR/monit5 &}
bind . <Control-Shift-C> { exec run -w $BINDIR/chekr &}
bind . <Control-Shift-E> { exec emacs &}
bind . <Control-Shift-L> { exec xterm -title logex -e $BINDIR/logex &}
bind . <Control-Shift-P> { exec xterm -title pfmed -e $BINDIR/pfmed &}
bind . <Control-Shift-S> { exec run -w $BINDIR/setcl &}
bind . <Control-Shift-T> { exec xterm -title fsset -e $BINDIR/fmset &}
bind . <Control-Shift-W> { exec xterm -ls -geom 80x24+75+75 -rw &}

########## Server FS ######################
# Log IO from STDOUT
# Run the program and arange to read its input.
proc FS {} {
    global command input log but .top.run .t line

    if [catch {open "|$command |& cat" } input] {
	.t delete 1.0 end
	.t insert end $input\n
    } else {
	.t delete 1.0 end
	fileevent $input readable Log
	.t insert end $command\n
        $but config -text "" -state disable -background navy -foreground White -command Running 
    update idletasks
    }
}

########## Server Log ######################
# Read and log output from the Field System.
proc Log {} {
    global input log newfile_filename but lskd .top.run sid
    global val01 val02 val03 val04 val05 val06 val07 val08 val08 val09
    global line semchk

 #   set val01 [exec vueinfo time]
    set val02 $newfile_filename
    set val03 [exec vueinfo rack]
    set val04 [exec vueinfo drive1]
    set val05 [exec vueinfo drive2]
    set val06 [exec vueinfo site]
    set val07 [exec vueinfo lskd]
    set val08 [exec vueinfo ifs]
    set val09 [exec vueinfo log]
    set newfile_filename $val09

    if { [gets $input line] <= 0 } {
	Stop
    } else {
        #
        # Start the Field System. If no other fsvue is running 
        # don't open the socket again.
        # 
	if { ![catch "socket -server server_accept 8433"] } {
            # Got to keep them separated.
            pack .sb -side right -fill y
            pack .t -side bottom -fill both -expand 1
            set val02 $newfile_filename
            set val03 [exec vueinfo rack]
            set val04 [exec vueinfo drive1]
            set val05 [exec vueinfo drive2]
            set val06 [exec vueinfo site]
            set val07 [exec vueinfo lskd]
            set val08 [exec vueinfo ifs]
            set val09 [exec vueinfo log]
            set newfile_filename $val09
	}
    
	update idletasks
	#regsub -all {\x1b\[0m} $line "" line
	#regsub -all {\[1;34m} $line "" line
	#regsub -all {\[1;31m} $line "" line
	#regsub -all {\[4m} $line "" line
	#regsub -all {\[5m} $line "" line
	#regsub -all {\[7m} $line "" line
	#regsub -all "\x1b" $line "" line
	if {[regexp "ERROR" $line] == 1} {
	    if {[regexp " ma " $line] == 1 || 
		[regexp " ch " $line] == 1 ||
		[regexp " bo " $line] == 1} {
		.t tag configure "red_rev" -background Red -foreground linen
		.t insert end $line\n red_rev
	    } elseif {[regexp " mc " $line] == 1 || 
		      [regexp " ib " $line] == 1 ||
		      [regexp " an " $line] == 1 ||
		      [regexp " ds " $line] == 1} {
		.t tag configure "red_und" -background Red -foreground white
		.t insert end $line\n red_und
	    } elseif {[regexp " ta " $line] == 1 ||
		      [regexp " wx " $line] == 1 ||
		      [regexp " sc " $line] == 1 } {
		.t tag configure "red" -background linen -foreground Red
		.t insert end $line\n red
	    } elseif {[regexp " if " $line] == 1 || 
		      [regexp " sp " $line] == 1 } {
		.t tag configure "blue" -background linen -foreground Blue
		.t insert end $line\n blue
	    } else {
		.t insert end $line\n ta
	    }
		.t see end
	} elseif {[regexp "terminate" $line] == 1 } {
	    update idletasks
	    .t insert end $line\n
	    pack .top.run -side top -fill both 
	    catch {exec killall oprin }
	    update idletasks
	} else {
	    if {[regexp ">  " $line] == 1 } {
		.t tag configure "red" -background linen -foreground Red
		.t insert end $line\n red
	    } else {
		.t insert end $line\n
	    }
	    .t see end
	}
	update idletasks
    }
}
########## Server Stop ####################
# Stop the program and fix up the button.
proc Stop {} {
    global input but line w sid

    catch { close $input}
    $but config -text \
	"<< (Left botton mouse click HERE) to start the Field System >>"\
	-relief raised -background blue -foreground white -state normal\
	-command FS
    catch { close $sid}
}

########## Field System and Server termination #########
# Stop the program and oprin.
proc Stop_FS { } {
    global input but line w sid cid

    catch {exec killall oprin }
    catch { close $input}
    catch { close $sid}
    catch { close $cid}
    catch {destroy $w}
    exit;
}

# Keep this incase we want to terminate the window when we type
# terminate from oprin.
#    catch {destroy $w}
#
#################################################################
# This command can be set to anything it just so happens that we
# want to start up the Field System.
#################################################################
set command "fs" 
#####################
set semchk [exec vueinfo chksem]
proc startfs {} {
    global semchk
    if {![regexp "fs already running" $semchk] } {
	# Startup the fsvue server if OLD fs is not ruuning.
	FS
    } else {
	# startup a client for fsvue if it is running.
	Start
    }
}
startfs
